package com.gzhryc.jdbc;

import com.gzhryc.jdbc.annotaion.Id;
import com.gzhryc.jdbc.annotaion.NumberBranchTable;
import com.gzhryc.jdbc.log.Logger;
import com.gzhryc.jdbc.models.ConnectInfo;
import com.gzhryc.jdbc.utils.EntityUtils;
import com.gzhryc.jdbc.utils.HelperUtils;

import java.io.File;
import java.lang.reflect.Field;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

public class NumberBranchHelper {

    static Logger log = Logger.getLogger(NumberBranchHelper.class);

    static NumberBranchHelper me;

    public static NumberBranchHelper self() {
        if (me == null) {
            me = new NumberBranchHelper();
        }
        return me;
    }

    private HashMap<String,Integer> data = new HashMap<>();
    private ConcurrentHashMap<String,AtomicLong> idGeneratorData = new ConcurrentHashMap<>();

    public void initial(ConnectInfo info,Class ... classes) {
        if(classes != null && classes.length > 0) {
            DbHelper helper = HelperUtils.createDbHelper(info.getKey());
            JdbcHelper jdbcHelper = HelperUtils.createJdbcHelper(info.getKey());
            for(Class clazz : classes) {
                NumberBranchTable branchTable = (NumberBranchTable) clazz.getAnnotation(NumberBranchTable.class);
                if(branchTable != null) {
                    String tableName = EntityUtils.getName(clazz);
                    Field idField = EntityUtils.getField(clazz,branchTable.keyFieldName());
                    if(idField != null){
                        Id idAnnotation = idField.getAnnotation(Id.class);
                        if(idAnnotation != null){
                            String idName = EntityUtils.getName(idField);
                            List<Long> ids = new ArrayList<>();
                            for (int i = 1; i <= 9; i++) {
                                String tempTableName = tableName + "_" + i;
                                try {
                                    if (helper.existTable(info.getDbName(), tempTableName)) {
                                        String sql = "SELECT MAX("+idName+") FROM " + tempTableName;
                                        Long result = jdbcHelper.getFirstField(new Query(sql),Long.class);
                                        if(result != null && result > 0){
                                            ids.add(Long.valueOf(result.toString().substring(1)));
                                        }
                                    }
                                } catch (SQLException e) {
                                    log.error(e.getMessage(),e);
                                }
                            }

                            Long autoIncrement = idAnnotation.autoIncrement();
                            if(ids.size() > 0){
                                for(Long id : ids){
                                    if(id > autoIncrement){
                                        autoIncrement = id;
                                    }
                                }
                            }
                            idGeneratorData.put(tableName,new AtomicLong(autoIncrement));
                        }
                    }else{
                        log.info("未能找到数字分表" + tableName + "的关键属性");
                    }


                }
            }
        }
    }

    public String getTableSuffixByTail(String key) {
        if (key != null && key.length() > 0) {
            String temp = key.substring(key.length() - 1);
            Integer num = data.get(temp);
            if (num == null) {
                num = 9;
            }
            return num.toString();
        }
        return "";
    }

    public String getTableSuffixByID(Long id){
        if (id != null && id > 0) {
            return id.toString().substring(0,1);
        }
        return "";
    }

    public AtomicLong getIdGenerator(String tableName){
        return idGeneratorData.get(tableName);
    }

    public NumberBranchHelper(){
        data.put("a",1);
        data.put("b",1);
        data.put("c",1);

        data.put("d",2);
        data.put("e",2);
        data.put("f",2);

        data.put("g",3);
        data.put("h",3);
        data.put("i",3);

        data.put("j",4);
        data.put("k",4);
        data.put("l",4);

        data.put("m",5);
        data.put("n",5);
        data.put("o",5);

        data.put("p",6);
        data.put("q",6);
        data.put("r",6);

        data.put("s",7);
        data.put("t",7);
        data.put("u",7);

        data.put("v",8);
        data.put("w",8);
        data.put("x",8);

        data.put("y",9);
        data.put("z",9);

        data.put("1",1);
        data.put("2",2);
        data.put("3",3);
        data.put("4",4);
        data.put("5",5);
        data.put("6",6);
        data.put("7",7);
        data.put("8",8);
        data.put("9",9);
    }

}
